package com.service;

import java.io.IOException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.dto.AllTicketsDTO;
import com.dto.IssueDTO;
import com.dto.WatchersDTO;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;

@Service
public class JiraService {
	@Autowired
	DatabaseService databaseService;
	@Autowired
	private HTTPBasicAuthFilter authFilter;
	@Autowired
	private String jiraUrl;

	/**
	 * Filling database with all tickets(may take a long time)
	 */
	public void fillDatabaseAllTickets() {

		int startAt = 0;
		boolean flag = true;
		AllTicketsDTO allTickets;

		Client client = Client.create();
		client.addFilter(authFilter);

		while (flag) {
			String uri = jiraUrl + "/rest/api/latest/search?startAt="
					+ startAt + "&maxResults=1000";
			WebResource service = client.resource(uri);
			String json = service.get(String.class);
			try {
				allTickets = mapJsonToDto(json, AllTicketsDTO.class);
				IssueDTO[] issues = allTickets.getIssues();
				if ((issues).length < 1000 || (issues).length == 0) {
					flag = false;
				}
				startAt += 1000;

				for (IssueDTO issue : issues) {
					issue.setWatchers(getDTOWatchers(issue.getKey()));
					fillDatabaseSingleTicket(issue.getKey());
				}
			} catch (JsonParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (JsonMappingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}

	/**
	 * maps json into DTO representation
	 * 
	 * @param json
	 *            as String
	 * @param clazz
	 *            value of Class.class
	 * @return DTO of type Class.class
	 */
	public <T> T mapJsonToDto(String json, Class<T> clazz)
			throws JsonParseException, JsonMappingException, IOException {
		ObjectMapper mapper = new ObjectMapper();
		T object = mapper.readValue(json, clazz);
		return object;
	}

	/**
	 * Returns single issue from Jira using rest api
	 * 
	 * @param ticketId
	 *            or key of the ticket
	 * @return IssueDTO
	 */
	public IssueDTO getSingleDto(String ticketId) throws JsonParseException,
			JsonMappingException, IOException {
		try {
			String uri =  jiraUrl + "/rest/api/latest/issue/" + ticketId;
			Client client = Client.create();
			client.addFilter(authFilter);
			WebResource service = client.resource(uri);
			String json = service.get(String.class);
			IssueDTO issue = mapJsonToDto(json, IssueDTO.class);
			issue.setWatchers(getDTOWatchers(issue.getKey()));
			return issue;
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return null;
	}

	/**
	 * Returns watchers from Jira using rest api for single ticket
	 * 
	 * @param ticketId
	 *            or key of the ticket
	 * @return WatchersDTO
	 */
	public WatchersDTO getDTOWatchers(String ticketId)
			throws JsonParseException, JsonMappingException, IOException {
		String uri =  jiraUrl + "/rest/api/latest/issue/" + ticketId
				+ "/watchers";
		Client client = Client.create();
		client.addFilter(authFilter);
		WebResource service = client.resource(uri);
		String jsonWatchers = service.get(String.class);
		WatchersDTO watchers = mapJsonToDto(jsonWatchers, WatchersDTO.class);
		return watchers;
	}

	/**
	 * Filling database with info from single ticket
	 * 
	 * @param ticketId
	 *            or key of the ticket
	 */
	public void fillDatabaseSingleTicket(String ticketId) {
		IssueDTO issueDto;
		try {
			issueDto = getSingleDto(ticketId);
			databaseService.issueIntoEntity(issueDto);
		} catch (JsonParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}